﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using STSdb4.Database;
namespace UcAsp.Net.NOSQLDAL
{
    class STSData
    {
        private object lockObject = new object();
        public string dataFileName { get; set; }
        private static STSData _data;
        public static STSData GetInstance
        {
            get
            {
                if (_data == null)
                {
                    _data = new STSData();
                    return _data;
                }
                else
                {
                    return _data;
                }
            }
        }
        public STSData()
        {
            dataFileName = AppDomain.CurrentDomain.BaseDirectory + "\\" + ConfigurationManager.AppSettings["dataFileName"];
        }
        public List<T> Select<T>(int pagesize, int pageindex)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    List<T> Result = new List<T>();
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    IEnumerable<KeyValuePair<long, T>> list = table.Skip(pagesize * pageindex).Take(pagesize);
                    foreach (KeyValuePair<long, T> row in list)
                    {
                        Result.Add(row.Value);
                    }
                    engine.Commit();
                    return Result;
                }
            }
        }

        public List<T> Select<T>()
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    List<T> Result = new List<T>();
                    if (engine.Exists(typeof(T).Name))
                    {
                        ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                        foreach (KeyValuePair<long, T> row in table)
                        {
                            Result.Add(row.Value);
                        }
                    }
                    engine.Commit();
                    return Result;
                }
            }
        }
        public List<T> Insert<T>(long key, List<T> value)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    foreach (T t in value)
                    {
                        table[key] = t;
                        key++;
                    }

                    engine.Commit();
                    return value;
                }
            }
        }
        public T Insert<T>(long key, T value)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    table[key] = value;

                    engine.Commit();
                    return value;
                }
            }
        }
        public T Update<T>(long key, T value)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    table.Replace(key, value);
                    engine.Commit();
                    return value;
                }
            }
        }
        public List<T> Update<T>(List<long> key, List<T> value)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    for (int i = 0; i < value.Count(); i++)
                    {
                        table.Replace(key[i], value[i]);
                    }

                    engine.Commit();
                    return value;
                }
            }
        }
        public T Find<T>(long key)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    T value = table.Find(key);

                    return value;
                }
            }
        }
        public void Delete<T>(long key)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    table.Delete(key);

                    engine.Commit();
                }
            }
        }
        public T FirstRow<T>(out long key)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                    if (table.Count() > 0)
                    {
                        KeyValuePair<long, T> firstrow = table.FirstRow;


                        key = firstrow.Key;
                        engine.Commit();
                        return firstrow.Value;
                    }
                    else
                    {
                        key = 0;
                        return default(T);
                    }
                }
            }
        }
        public T LastRow<T>(out long key)
        {
            lock (this)
            {
                using (IStorageEngine engine = STSdb.FromFile(dataFileName))
                {
                    try
                    {
                        ITable<long, T> table = engine.OpenXTable<long, T>(typeof(T).Name);
                        if (table.Count() > 0)
                        {
                            KeyValuePair<long, T> lastrow = table.LastRow;

                            engine.Commit();
                            key = lastrow.Key;
                            return lastrow.Value;
                        }
                        else
                        {
                            key = 0;
                            return default(T);
                        }
                    }
                    catch
                    {
                        key = 0;
                        return default(T);
                    }
                }
            }
        }
    }
}